/*
 * GeoVISTA Center (Penn State, Dept. of Geography)
 * Copyright (c), 2003-2011,  Jin Chen and Alan M. MacEachren, GeoVISTA Center, Penn State University
 * Licensed under Simplified BSD License
 *
 * A Panel display a set of color swatches (JLabel). The swatch's size is fixed, not change along with the change to the size of their container panel
 * @Original Author: jin Chen
 * @date: Nov 23, 2004$
 * @version: 1.0
 */
package edu.psu.geovista.app.visualclassifier.classify.v2.colorpalette.v2;

import edu.psu.geovista.app.visualclassifier.classify.v2.colorpalette.FixedSwatchPane;

import javax.swing.*;
import javax.swing.event.MouseInputAdapter;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Iterator;

public class FixedSwatchPaneImpl extends JPanel implements FixedSwatchPane {
    public static final String SELECT_COLOR="CC";//SELECT A COLOR
    public static final int GAP_WIDTH=5;
    public static final int GAP_HEIGHT=5;
    public static final Color COLOR_DEFAULT=Color.blue ; //for testing
    //protected Color[][] colors;
    protected Dimension swatchSize=new Dimension();
    //protected Dimension numSwatches;//num of swatch
    protected int numOfRow;
    protected int numOfCulumn;
    protected Dimension gap=new Dimension(-1,-1);//gap between any 2 swatches
    protected boolean outlineSquare;// make a outline in black color for the square
    protected JPanel mainP;
    protected MouseInputAdapter swatchListener=new MyMouseAdapter();
    protected java.util.List swatches=new ArrayList();

    //private boolean swatchSizeChangable=false;
    //create a 3x8 panel with default color
    /**
     *
     * @param width  the size of a single swatch
     * @param height
     */
    public FixedSwatchPaneImpl(int width, int height) {
       //System.out.println("");
        this(width,height,3,8);
        int[][] colorValues=new int[][]{
            {255, 255, 255, // first row.
                192, 192, 192,
                255, 0, 0,
                255, 255, 0,
                0, 255, 0,
                0, 255, 255,
                0, 0, 255,
                255, 0, 255},
            {0, 0, 0,  // second row.
                128, 128, 128,
                128, 0, 0,
                128, 128, 0,
                0, 128, 0,
                0, 128, 128,
                0, 0, 128,
                128, 0, 128,},
            {255, 199, 199,  // 3rd row.
                83, 109, 165,
                204,  255,204,
                153, 153, 204,
                204, 204, 214,
                0, 180, 110,
                252, 253, 205,
                212, 133, 213}
        };
        Color[][] mycolors= convert2RowBased(colorValues);
        this.setColors(mycolors);
    }
     public FixedSwatchPaneImpl(int width, int height, int[][] colorvalues){
         this(width,height, convert2RowBased(colorvalues));
     }
     public FixedSwatchPaneImpl(int width, int height, Color[][] colors){
        this.swatchSize.width =width;
        this.swatchSize.height=height;
        this.numOfRow = colors.length ;
        this.numOfCulumn= colors[0].length ;
        //this.colors=colors;
        init(colors);

     }

    public FixedSwatchPaneImpl(int width, int height, Color[][] colors, Dimension gap){
        this.swatchSize.width =width;
        this.swatchSize.height=height;
        this.numOfRow = colors.length ;
        this.numOfCulumn= colors[0].length ;
        this.gap=gap;
        init(colors);

     }
    public FixedSwatchPaneImpl(int width, int height, int numOfrow, int numOfColumn) {
        this.swatchSize.width =width;
         this.swatchSize.height=height;
        this.numOfRow = numOfrow;
        this.numOfCulumn= numOfColumn;
        init(null);
    }

    public static Color[][] convert2RowBased(int[][] values){
          int row=values.length ;
          int col=values[0].length/3 ;

          Color[][] mycolors=new Color[row][col];

          for (int i=0;i<row ;i++){//rows
                int[] rowv=values[i];
                Color[] colors=new Color[col];
                for (int j=0;j<col ;j++){
                     colors[j] = new Color( rowv[(j*3)], rowv[(j*3)+1], rowv[(j*3)+2] );
                     //System.out.println("a color:"+colors[j]);
                }
                 mycolors[i]=colors;
          }
        return mycolors;

    }
    public static Color[][] convert2ColumnBased(int[][] values){
          int col=values.length ;
          int row=values[0].length/3 ;

          Color[][] mycolors=new Color[row][col];

          for (int i=0;i<col ;i++){//rows
                int[] rowv=values[i];
                Color[] colors=new Color[col];
                for (int j=0;j<row ;j++){
                     colors[j] = new Color( rowv[(j*3)], rowv[(j*3)+1], rowv[(j*3)+2] );
                     //System.out.println("a color:"+colors[j]);
                }
                 mycolors[i]=colors;
          }
        return mycolors;

    }
    /**
     * gap.width   gap in horizontal direction
     * gap.height  gap in vertical direction
     * @param gap
     */
    public void setGap(Dimension gap) {
        this.gap = gap;
    }
    public void setSwatchBorderColor(Color c){
        for (Iterator iterator = swatches.iterator(); iterator.hasNext();) {
            JLabel label = (JLabel) iterator.next();
            label.setBorder(new javax.swing.border.LineBorder(c));//);

        }
        this.mainP.repaint();
    }
   /* public void setPreferredSize(Dimension d) {

        super.setPreferredSize(d);
        if(this.isSwatchSizeChangable()){
            Dimension size = this.getSize();
            int w=(int) (size.getWidth() /numOfRow);
            int h=(int) (size.getHeight()/this.numOfCulumn);
            setSwatchSize(new Dimension(w,h));
        }
    }*/

    public void setSwatchSize(Dimension d){
        this.swatchSize.setSize(d);
        for (Iterator iterator = swatches.iterator(); iterator.hasNext();) {
            JLabel label = (JLabel) iterator.next();
            label.setPreferredSize(swatchSize);

        }
        this.mainP.revalidate();
        this.mainP.repaint();
    }

   /* public boolean isSwatchSizeChangable() {
        return swatchSizeChangable;
    }

    public void setSwatchSizeChangable(boolean swatchSizeChangable) {
        this.swatchSizeChangable = swatchSizeChangable;
    }*/

    protected void init(Color[][] colors){
        //set  gap   as default
        this.swatches.clear();
        if(gap.width<0)
            gap.width =GAP_WIDTH;
        if(gap.height<0)
            gap.height =GAP_HEIGHT;

        //default color
        if(colors==null) {
            colors=new Color[numOfRow][numOfCulumn];
            for (int i=0;i<numOfRow;i++){
                for (int j=0;j<numOfCulumn;j++){
                    colors[i][j]=COLOR_DEFAULT;
                }
            }
        }

        if ( mainP==null)
             mainP=new JPanel();
        this.mainP.removeAll();
        mainP.setLayout(new java.awt.GridLayout(numOfRow, numOfCulumn, gap.width, gap.height));

        for (int i=0;i<numOfRow;i++){
                for (int j=0;j<numOfCulumn;j++){
                    JLabel swatch = createSwatch(colors[i][j]);
                    this.swatches.add(swatch);
                    mainP.add(swatch);
                    swatch.addMouseListener(swatchListener);

                }
            } //for loop
        //use GridBagLayout and mainP to make sure to keep the swatch size as specified as the panel size changed
        this.setLayout(new GridBagLayout());
         this.add(mainP);


       /* this.addComponentListener(new ComponentAdapter(){
            public void componentResized(ComponentEvent e){
                   if(isSwatchSizeChangable()){
                        Dimension size = getSize();
                        int w=(int) (size.getWidth() /numOfRow);
                        int h=(int) (size.getHeight()/numOfCulumn);
                        setSwatchSize(new Dimension(w,h));
                    }
            }
        });*/
    }



    private JLabel createSwatch(Color color) {
        JLabel swatch = new ColorLabel();
        swatch.setPreferredSize(new Dimension(swatchSize.width , swatchSize.height ));
        swatch.setBorder(new javax.swing.border.LineBorder(new Color(0, 0, 0)));
        swatch.setBackground(color);
        swatch.setOpaque(true);
        swatch.setToolTipText("RGB:"+color.getRed() +","+color.getGreen() +","+color.getBlue() );
        return swatch;
    }
    /**
     *  
     * u can overrid the method to define customized behavior
     */
    public void mouseClicked(MouseEvent e){
        JLabel label=(JLabel) e.getSource();
        Color bgcolor = label.getBackground();
             //System.out.println(" click on swatch:"+bgcolor);
        this.firePropertyChange(SELECT_COLOR,null,bgcolor);
    }
    public void setColors(Color[][] colors) {

        this.init(colors);
    }

    //listen to sample label
    class MyMouseAdapter extends MouseInputAdapter{
         public void mouseClicked(MouseEvent e){
                  FixedSwatchPaneImpl.this.mouseClicked(e);

         }
    }

    public static class ColorLabel extends JLabel{
          public void setBackground(Color bg) {
              if(bg!=null){
              super.setBackground(bg);

              this.setToolTipText("RGB:"+bg.getRed() +","+bg.getGreen() +","+bg.getBlue() );
              }
          }
    }



   


}
